package gameObject.resources3D
{
	import assets.Asset;
	
	import away3d.animators.SkeletonAnimator;
	
	import com.riaidea.utils.zip.ZipArchive;
	import com.riaidea.utils.zip.ZipEvent;
	import com.riaidea.utils.zip.ZipFile;
	
	import events.LoadedEvent;
	
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	/**
	 * 把整个地图资源（除了贴图）打包在一个zip文件中加载
	 */
	public class MapResource extends ResourceBase
	{
		private var loader:URLLoader;
		private var zip:ZipArchive;
		private var _assetURL:String
		private var _colMapURL:String;
		private var _xml:XML;
		
		private var _meshes:Vector.<GameMesh>;
		private var _collisionMap:BitmapData;
		private var _groundMesh:GameMesh;
		
		private var _totalAsset:int = 0;
		private var _loadedAsset:int = 0;
		
		private var _startX:Number;
		private var _startY:Number;
		private var _width:Number;
		private var _height:Number;
		
		/////////////////////////////////////////////
		public function get meshes():Vector.<GameMesh>
		{
			return _meshes;
		}

		public function get groundMesh():GameMesh
		{
			return _groundMesh;
		}
		
		public function get collisionMap():BitmapData
		{
			return _collisionMap;
		}
		
		public function get startX():Number
		{
			return _startX;
		}
		
		public function get startY():Number
		{
			return _startY;
		}
		
		public function get width():Number
		{
			return _width;
		}
		
		public function get height():Number
		{
			return _height;
		}
		/////////////////////////////////////////////
		public function MapResource(ID:int)
		{
			super();
			_id = ID;
			
		}
		
		override public function load():void
		{
			if(_id>=0 && !_meshes)
			{
				_meshes = new Vector.<GameMesh>;
				_assetURL =  Global.assetPath+"models/maps/map"+String(_id)+".zip";
				
				loader = new URLLoader;
				loader.dataFormat=URLLoaderDataFormat.BINARY;
				loader.addEventListener(Event.COMPLETE,onDataLoaded);
				loader.load(new URLRequest(_assetURL));
			}
		}
		private function onError(e:ZipEvent):void
		{
			var errorInfo:String ="ZIP资源异常："+ _assetURL;
			throw new Error(errorInfo);
		}
		
		override public function dispose():void
		{
			super.dispose();
			
			zip.removeEventListener(ZipEvent.INIT,mapFileLoaded);
			zip.removeEventListener(ZipEvent.ERROR,onError);
			
			for each(var mesh:GameMesh in _meshes)
			{
				if(mesh.type==GameMesh.TYPE_SKINNED)
				{
					var animator:SkeletonAnimator = mesh.animator as SkeletonAnimator;
					animator.stop();
				}
			}
		}
	
		private function onDataLoaded(e:Event):void
		{
			loader.removeEventListener(Event.COMPLETE,onDataLoaded);
			var data:ByteArray = loader.data;
			
			executeData(data);
		}
		
		private function executeData(data:ByteArray):void
		{
			zip = new ZipArchive;
			zip.addEventListener(ZipEvent.ERROR,onError);
			zip.addEventListener(ZipEvent.INIT,mapFileLoaded);
			zip.open(data);
		}
		
		private function mapFileLoaded(e:ZipEvent):void
		{
			zip.removeEventListener(ZipEvent.INIT,mapFileLoaded);
			zip.removeEventListener(ZipEvent.ERROR,onError);
			
			var xmlName:String = "map"+String(_id)+"_ini.xml";
			var xmlFile:ZipFile = zip.getFileByName(xmlName);
			_xml = new XML(xmlFile.data);
			
			//设置地图边界
			var borderStr:String = _xml.border;
			var strAry:Array = borderStr.split(",");
			_startX = Number(strAry[0]);
			_startY = Number(strAry[1]);
			_width = Number(strAry[2]);
			_height = Number(strAry[3]);
			
			//取出碰撞图
			var colMapName:String = _xml.collisionMap;
			if(colMapName!="")
			{
				_colMapURL = Global.assetPath+"bitmaps/"+colMapName;
				_totalAsset++;
				
				Asset.bitmapdata.addEventListener(LoadedEvent.BITMAPDATA_COMPLETE,gotColMap);
				Asset.bitmapdata.load(_colMapURL);
			}
			
			//设置灯光
			var lightXML:XML = new XML(_xml.lights)
			Global.gameView.getLight(lightXML);
			/////////////////////////////////////////
			
			//取出地面物体
			var meshName:String = _xml.ground.@name;
			
			var zipFile:ZipFile =  zip.getFileByName(meshName);
			var meshData:XML = new XML(zipFile.data);
			
			var meshURL:String = Global.assetPath+"models/maps/"+meshName;
			_groundMesh = new GameMesh(meshURL,meshData);
			var ary:Array = meshName.split(/_/);
			_groundMesh.name = ary[1];
			
			_groundMesh.x = Number(_xml.ground.@posX);
			_groundMesh.y = Number(_xml.ground.@posZ);
			_groundMesh.z = Number(_xml.ground.@posY);
			
			_groundMesh.rotationX = -Number(_xml.ground.@rotX);
			_groundMesh.rotationY = -Number(_xml.ground.@rotY);
			_groundMesh.rotationZ = -Number(_xml.ground.@rotZ);
			
			_groundMesh.scaleX = _xml.ground.@scaX;
			_groundMesh.scaleY = _xml.ground.@scaZ;
			_groundMesh.scaleZ = _xml.ground.@scaY;
			
			_totalAsset++;
			_groundMesh.addEventListener(Event.COMPLETE,gotAsset);
			addChild(_groundMesh);
			//取出地图中的物体
			for each(var meshInfo:XML in _xml.meshes.mesh)
			{
				meshName = meshInfo.@name;
				zipFile =  zip.getFileByName(meshName);
				meshData = new XML(zipFile.data);
				
				var skeletonData:XML=null;
				var skeURL:String = meshData.@skeleton;
				
				if(skeURL != "")
				{
					zipFile =  zip.getFileByName(skeURL);
					skeletonData = new XML(zipFile.data);
				}
				
				meshURL = Global.assetPath+"models/maps/"+meshName;
				var mesh:GameMesh = new GameMesh(meshURL,meshData,skeletonData);
				ary = meshName.split(/_/);
				mesh.name = ary[1];
				
				mesh.x = Number(meshInfo.@posX);
				mesh.y = Number(meshInfo.@posZ);
				mesh.z = Number(meshInfo.@posY);
				
				mesh.rotationX = -Number(meshInfo.@rotX);
				mesh.rotationY = -Number(meshInfo.@rotY);
				mesh.rotationZ = -Number(meshInfo.@rotZ);
				
				mesh.scaleX = meshInfo.@scaY;
				mesh.scaleY = meshInfo.@scaZ;
				mesh.scaleZ = meshInfo.@scaX;
				
				_meshes.push(mesh);
				_totalAsset++;
				
				addChild(mesh);
			}
			
			_groundMesh.load();
			for each(mesh in _meshes)
			{
				mesh.addEventListener(Event.COMPLETE,gotAsset);
				mesh.load();
			}
		}
		
		private function gotAsset(e:Event):void//收到模型资源
		{
			var mesh:GameMesh = e.currentTarget as GameMesh;
			mesh.removeEventListener(Event.COMPLETE,gotAsset);
			
			if(mesh.type == GameMesh.TYPE_SKINNED)
			{
				var animator:SkeletonAnimator = mesh.animator as SkeletonAnimator;
				animator.play(mesh.animationNames[0]);
			}
			
			_loadedAsset++;
			if(_loadedAsset == _totalAsset)complete();
		}
		
		private function gotColMap(e:LoadedEvent):void//收到碰撞图
		{
			if(e.URL==_colMapURL)
			{
				Asset.bitmapdata.removeEventListener(LoadedEvent.BITMAPDATA_COMPLETE,gotColMap);
				_collisionMap = Asset.resBitmapDatas[_colMapURL];
				
				_loadedAsset++;
				if(_loadedAsset == _totalAsset)complete();
			}
		}
		
		private function complete():void
		{
//			addChild(_groundMesh);
//			for each(var mesh:GameMesh in _meshes)addChild(mesh);
			
			Global.mapResources[_id] = this;
			dispatchEvent(new Event(Event.COMPLETE));
		}
	}
}